﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;

using Excel = Microsoft.Office.Interop.Excel;

namespace Utilites
{
    public static class FileUtilites
    {
        ///// <summary>
        ///// Сохраняет первый загруженный файл на диск по указанному пути с указанным именем
        ///// </summary>
        ///// <param name="files"></param>
        ///// <param name="fileName"></param>
        ///// <param name="path"></param>
        //public static string SaveUplodedFile(IEnumerable<HttpPostedFileBase> files, string fileName, string path)
        //{
        //    if (files == null || string.IsNullOrEmpty(fileName) || string.IsNullOrEmpty(path)) return null;
        //    try
        //    {
        //        files.First().SaveAs(Path.Combine(path, fileName));
        //    }
        //    catch (Exception)
        //    {
        //        return null;
        //    }
        //    return Path.Combine(path, fileName);
        //}

        /// <summary>
        /// Сохраняет загруженный файл на диск по указанному пути с указанным именем
        /// </summary>
        /// <param name="file"></param>
        /// <param name="fileName"></param>
        /// <param name="path"></param>
        public static string SaveUplodedFile(HttpPostedFileBase file, string fileName, string path)
        {
            if (file == null) return null;
            if (string.IsNullOrEmpty(fileName)) return null;
            if (string.IsNullOrEmpty(path)) return null;
            try
            {
                file.SaveAs(Path.Combine(path, fileName));
            }
            catch (Exception)
            {
                return null;
            }
            return Path.Combine(path, fileName);
        }

        /// <summary>
        /// Проверят тип файла по имени
        /// </summary>
        /// <returns></returns>
        public static bool ValidateExtention(HttpPostedFileBase file,  string ext)
        {
            if (file == null) return false;
            var fileExt = file.FileName.Split('.').Last();
            return fileExt.ToUpper().Trim() == ext.ToUpper().Trim();
        }

        /// <summary>
        /// возвращает расширение файла в нижнем регистре
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static string GetFileExtention(HttpPostedFileBase file)
        {
            return file == null ? null : file.FileName.Split('.').Last().ToLower();
        }

        #region Excel utilites

        /// <summary>
        /// Читает первый лист Excel файла и возвращает информацию в виде DataTable
        /// </summary>
        /// <param name="filepath">полный путь к файлу</param>
        /// <param name="worksheetNumber">по умолчанию номер первого листа = 0</param>
        /// <returns>DataTable или null, если ни ожного ряда не прочитанно</returns>
        public static DataTable GetDataTableFromXlsFile(string filepath, int worksheetNumber = 0)
        {
            //проверка наличия файла
            if (string.IsNullOrEmpty(filepath)) return null;
            if (!File.Exists(filepath)) return null;

            string listName = GetExcelWorksheetsName(filepath)[worksheetNumber];
            //выбор строки подключения, в зависимости от формата файла
            string connectionString = null;
            string connectionString2003 = string.Format("provider=Microsoft.Jet.OLEDB.4.0;data source={0};Extended Properties=Excel 8.0;", filepath);
            string connectionString2007 = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;data source={0};Extended Properties=\"Excel 12.0 Xml;HDR=YES\"", filepath);
            string[] fileFeilds = filepath.Split('.');
            int length = fileFeilds.Length;
            if (fileFeilds[length - 1] == "xls" || fileFeilds[length - 1] == "XLS")
                connectionString = connectionString2003;
            if (fileFeilds[length - 1] == "xlsx" || fileFeilds[length - 1] == "XLSX")
                connectionString = connectionString2007;
            if (string.IsNullOrEmpty(connectionString)) return null;
            
            //формирование запроса
            string queryString = string.Format("SELECT * FROM [{0}$]", listName);
            //подключение к базе
            OleDbConnection oleDbConnection = new OleDbConnection(connectionString);
            oleDbConnection.Open();
            OleDbDataAdapter dataAdapter = new OleDbDataAdapter(queryString, oleDbConnection);
            DataTable dataTable = new DataTable();
            //заполнение DataSet
            var rowsCount = dataAdapter.Fill(dataTable);
            //закрытие файла
            oleDbConnection.Close();
            if (rowsCount < 1) return null;
            return dataTable;
        }

        /// <summary>
        /// Находит в Excel файле все листы и возвращает массив имен этих листов
        /// </summary>
        /// <param name="ExcelFileName">Имя Excel файла</param>
        /// <returns>Масив имен листов файла</returns>
        public static string[] GetExcelWorksheetsName(string ExcelFileName)
        {
            string[] Names = null;

            Excel.Application ExApp = null;
            Excel.Workbook ExWB = null;

            try
            {
                ExApp = new Excel.Application();
                ExWB = ExApp.Workbooks.Open(ExcelFileName, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
                Names = new string[ExWB.Worksheets.Count];
                int i = 0;
                foreach (Excel.Worksheet ExWS in ExWB.Worksheets)
                {
                    Names[i] = ExWS.Name;
                    i++;
                }
                ExWB.Close(Missing.Value, ExcelFileName, Missing.Value);
                ExWB = null;
                ExApp.Quit();
                ExApp = null;
            }
            catch (Exception ex)
            {
                // MessageBox.Show(ex.Message, "Поиск имен листов", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if (ExWB != null)
                {
                    ExWB.Close(null, ExcelFileName, null);
                    ExWB = null;
                }
                if (ExApp != null)
                {
                    ExApp.Quit();
                    ExApp = null;
                }
                //Ускоряем удаление объектов из памяти.
                GC.Collect();
            }
            return Names;
        }
        
        #endregion
    }
}
